import { useState } from 'react';
import { Input, TreeProps } from 'antd';
import { useMemoizedFn } from 'ahooks';

export interface ActionType {
  startEdit: () => void;
  removeNode: () => void;
  insertNode: (newNodeData: any) => void;
}

const useTreeEdit = (options: {
  loop: Function;
  checkSameName: Function;
  fieldNames?: TreeProps['fieldNames'];
  treeData?: any[];
  forceUpdate?: () => void;
}) => {
  const { loop, checkSameName, fieldNames, treeData, forceUpdate } = options;
  const { key = 'key', title = 'title' } = fieldNames ?? {};

  // 编辑相关
  const [editNode, setEditNode] = useState<any>(null); // 正在编辑的节点
  const [editValue, setEditValue] = useState(''); // 编辑框中的值

  // 节点编辑
  const treeAction = useMemoizedFn((id: any, fn: Function) => {
    loop(treeData, id, fn);
    forceUpdate && forceUpdate();
  });

  // 删除节点
  const removeNode = useMemoizedFn((nodeData: any) => {
    treeAction(nodeData[key], (node, index, parent) => {
      parent.splice(index, 1);
    });
  });

  // 插入节点
  const insertNode = useMemoizedFn((nodeData: any, newNodeData: any) => {
    treeAction(nodeData[key], (node, index, parent) => {
      parent.splice(index, 0, newNodeData);
    });
  });

  // 开始编辑
  const startEdit = useMemoizedFn((node) => {
    setEditNode(node);
    setEditValue(node[title]);
  });

  // 处理编辑完成
  const onEditEnd = useMemoizedFn(() => {
    // 无效值
    if (!editNode || !editValue) {
      setEditNode(null);
      return;
    }

    // 查找对应的同级节点
    loop(treeData, editNode[key], (node, index, arr) => {
      // 重名校验
      checkSameName({ ...node, [title]: editValue }, arr)
        .then(() => {
          // 名称没有发生改变，减少dom更新次数
          if (editNode[title] === editValue) return;

          // title更新
          editNode[title] = editValue;
          // 强制刷新
          forceUpdate && forceUpdate();
        })
        .finally(() => {
          // 取消正在编辑的节点
          setEditNode(null);
        });
    });
  });

  // 节点的标题渲染函数
  const titleWrapper = useMemoizedFn((node, render: (action: ActionType) => JSX.Element) => {
    // 开启编辑的时候，允许编辑
    if (editNode === node) {
      return (
        <Input
          value={editValue}
          onChange={(e) => setEditValue(e.target.value)}
          onBlur={onEditEnd}
          onPressEnter={(e) => e.currentTarget.blur()}
          autoFocus
        />
      );
    }

    // 常规模式
    return render({
      startEdit: () => startEdit(node),
      removeNode: () => removeNode(node),
      insertNode: (newNodeData) => insertNode(node, newNodeData),
    });
  });

  return { titleWrapper };
};

export default useTreeEdit;
